#include <QVariantMap>
#include <yaml-cpp/yaml.h>
#include "Utility.h"

QVariant yamlNodeQVariant(YAML::Node param)
{
    QVariant out;
    if (param.IsScalar()) {
        // 支持 QString、int、float 等类型
        try {
            out = QVariant::fromValue(param.as<int>());
        } catch (...) {
            try {
                out = QVariant::fromValue(param.as<float>());
            } catch (...) {
                out = QString::fromStdString(param.as<std::string>());
            }
        }
    } else if (param.IsSequence()) {
        QVariantList list;
        for (YAML::const_iterator it = param.begin(); it != param.end(); ++it) {
            // 支持整数和浮点数
            try {
                list << QVariant::fromValue(it->as<int>());
            } catch (...) {
                try {
                    list << QVariant::fromValue(it->as<float>());
                } catch (...) {
                    list << QString::fromStdString(it->as<std::string>());
                }
            }
        }
        out = list;
    } else if (param.IsMap()) {
        QVariantMap subMap;
        for (YAML::const_iterator subIt = param.begin(); subIt != param.end(); ++subIt) {
            subMap[QString::fromStdString(subIt->first.as<std::string>())] = QString::fromStdString(subIt->second.as<std::string>());
        }
        out = subMap;
    }
    return out;
}

QVariant yamliteratorQVariant(YAML::const_iterator param)
{
    QVariant out;
    if (param->second.IsScalar()) {
        // 支持 QString、int、float 等类型
        try {
            out = QVariant::fromValue(param->second.as<int>());
        } catch (...) {
            try {
                out = QVariant::fromValue(param->second.as<float>());
            } catch (...) {
                out = QString::fromStdString(param->second.as<std::string>());
            }
        }
    } else if (param->second.IsSequence()) {
        QVariantList list;
        for (YAML::const_iterator it = param->second.begin(); it != param->second.end(); ++it) {
            // 支持整数和浮点数
            try {
                list << QVariant::fromValue(it->as<int>());
            } catch (...) {
                try {
                    list << QVariant::fromValue(it->as<float>());
                } catch (...) {
                    list << QString::fromStdString(it->as<std::string>());
                }
            }
        }
        out = list;
    } else if (param->second.IsMap()) {
        QVariantMap subMap;
        for (YAML::const_iterator subIt = param->second.begin(); subIt != param->second.end(); ++subIt) {
            subMap[QString::fromStdString(subIt->first.as<std::string>())] = QString::fromStdString(subIt->second.as<std::string>());
        }
        out = subMap;
    }
    return out;
}

std::string QVariantToString(const QVariant &value, int indentLevel) {
    std::ostringstream out;
    QString indent(indentLevel * 2, ' ');

    if (value.type() == QVariant::Map) {
        out << "\n" << QVariantMapToString(value.toMap(), indentLevel + 1);
    } else if (value.type() == QVariant::List) {
        out << "\n" << QVariantListToString(value.toList(), indentLevel + 1);
    } else {
        out << value.toString().toStdString();
    }

    return out.str();
}

std::string QVariantMapToString(const QVariantMap &map, int indentLevel) {
    std::ostringstream out;
    QString indent(indentLevel * 2, ' ');

    for (auto it = map.cbegin(); it != map.cend(); ++it) {
        out << indent.toStdString() << it.key().toStdString() << ": ";
        out << QVariantToString(it.value(), indentLevel) << "\n";
    }

    return out.str();
}

// std::string QVariantListToString(const QVariantList &list, int indentLevel) {
//     std::ostringstream out;
//     QString indent(indentLevel * 2, ' ');

//     for (int i = 0; i < list.size(); ++i) {
//         out << indent.toStdString() << "- " << QVariantToString(list[i], indentLevel) << "\n";
//     }

//     return out.str();
// }

